package com.donlim.dev.component;

import com.donlim.dev.annotation.PassToken;
import com.donlim.dev.entity.SysUser;
import com.donlim.dev.enums.ExceptionCode;
import com.donlim.dev.enums.ResultCode;
import com.donlim.dev.exception.SysUserException;
import com.donlim.dev.service.SysUserService;
import com.donlim.dev.utils.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 * Created by 星 on 2020/11/4
 * JWT 登录认证 过滤器
 */
@Slf4j
public class JwtAuthenticationTokenFilter implements HandlerInterceptor {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private SysUserService sysUserService;
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

//
//    @Override
//    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
//                                    FilterChain filterChain) throws ServletException, IOException {
//
//        String authHeader = httpServletRequest.getHeader(tokenHeader);
//        if (authHeader != null && authHeader.startsWith(tokenHead)){
//            String authToken = authHeader.substring(tokenHead.length());
//            String codeFromToken = jwtTokenUtil.getUserCodeFromToken(authToken);
//            log.info("JWT checking userCode:{}",codeFromToken);
//            if (!StringUtils.isEmpty(codeFromToken)){
//                try {
//                    SysUser sysUser = sysUserService.loadUserByUserCode(codeFromToken);
//                    //验证JWT

//                    if (!jwtTokenUtil.validateToken(authToken,sysUser)){
//                        throw new SysUserException(ResultCode.UNAUTHORIZED.getCode(),ResultCode.UNAUTHORIZED.getMessage());
//                    }
//                    log.info("JWT authenticated userCode:{}",codeFromToken);
//                } catch (SysUserException e) {
//                    e.printStackTrace();
//                }
//            }
//
//        }
//        filterChain.doFilter(httpServletRequest,httpServletResponse);
//
//    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //不是方法 通过
        if (!(handler instanceof HandlerMethod)) return true;

        //有PassToken注解 并且属性为true 通过
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        Method method = handlerMethod.getMethod();
        if (method.isAnnotationPresent(PassToken.class)){
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) return true;
        }else { //没有PassToken注解 或注解值为false 都要验证
            String authToken = request.getHeader(tokenHeader);
            if (authToken != null) {
                String codeFromToken = jwtTokenUtil.getUserCodeFromToken(authToken);
                log.info("JWT checking userCode:{}", codeFromToken);
                if (!StringUtils.isEmpty(codeFromToken)) {
                    try {
                        SysUser sysUser = sysUserService.loadUserByUserCode(codeFromToken);
                        //验证JWT
                        if (!jwtTokenUtil.validateToken(authToken, sysUser)) {
                            throw new SysUserException(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage());
                        }
                        log.info("JWT authenticated userCode:{}", codeFromToken);
                        return true;
                    } catch (SysUserException e) {
                        e.printStackTrace();
                    }
                }
            }
            throw new SysUserException(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage());
        }
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
